Skip to content

feat(auth): in-app Twitch sign-in flow#78

Merged
ImpulseB23 merged 4 commits intomainfrom
feat/twitch-auth-ui
Apr 17, 2026
Merged

feat(auth): in-app Twitch sign-in flow#78
ImpulseB23 merged 4 commits intomainfrom
feat/twitch-auth-ui

Conversation

@ImpulseB23
Copy link
Copy Markdown
Owner

Closes the Phase 1 OAuth UX gap by surfacing the existing Device Code Grant backend through Tauri commands and a SignIn overlay, so non-developers can run Prismoid without editing files or running CLI tools.

What's new

Tauri commands (twitch_auth/commands.rs):

  • twitch_auth_status — peeks the keychain to choose SignIn vs ChatFeed
  • twitch_start_login — kicks off DCF, returns user_code + verification_uri
  • twitch_complete_login — awaits authorization, persists tokens, fires wakeup
  • twitch_cancel_login — clears the pending flow slot
  • twitch_logout — wipes the keychain entry, fires wakeup

Shared state: AuthState { manager: Arc<AuthManager>, pending: Mutex<Option<PendingDeviceFlow>>, wakeup: Arc<Notify> }. Supervisor and commands hold clones of the same AuthManager and Notify, so a successful sign-in wakes the supervisor's waiting_for_auth sleep within milliseconds instead of forcing a 30 s wait.

Frontend (App.tsx, components/SignIn.tsx, lib/twitchAuth.ts):

  • Boot reads twitch_auth_status → splash → SignIn or ChatFeed
  • SignIn: one button → opens browser → shows user_code while polling completes → on success, mounts ChatFeed
  • Friendly error mapping for user_denied, device_code_expired, keychain, oauth, no_pending_flow

Capability: tauri.conf.json now allows shell.open only for https://(?:id|www)\.twitch\.tv/.

Tests

  • Rust: 117 lib tests (+10 new) — error mapping, status serialization, store/wakeup roundtrip
  • Go: all packages pass (no Go changes)
  • TS: 30 tests, lint clean, typecheck clean
  • Clippy: clean with -D warnings

The prismoid_dcf dev tool still works for headless seeding.

Adds Tauri command surface and SignIn overlay so non-developers can
sign in without running the prismoid_dcf CLI tool. Closes the OAuth
UX gap in Phase 1.
Copilot AI review requested due to automatic review settings April 17, 2026 20:12
@github-actions github-actions bot added size/l 500-1000 lines changed rust Rust/Tauri changes typescript Frontend/TypeScript changes and removed size/l 500-1000 lines changed labels Apr 17, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 17, 2026

Codecov Report

❌ Patch coverage is 87.31707% with 26 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ps/desktop/src-tauri/src/twitch_auth/auth_state.rs 91.05% 17 Missing ⚠️
apps/desktop/src-tauri/src/sidecar_supervisor.rs 0.00% 9 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an in-app Twitch OAuth Device Code Grant (DCF) sign-in UX by exposing the existing Rust auth manager through new Tauri commands and a SolidJS SignIn overlay, plus wiring a wake-up notifier so the Windows sidecar supervisor can react immediately to login/logout.

Changes:

  • Added a frontend auth client + SignIn overlay that drives the DCF flow and gates ChatFeed on login state.
  • Added new Tauri commands (twitch_auth_status, twitch_start_login, twitch_complete_login, twitch_cancel_login, twitch_logout) with shared AuthState.
  • Updated the Windows sidecar supervisor to wait on a shared Notify (with a 30s timeout fallback) instead of fixed sleeping.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
apps/desktop/src/lib/twitchAuth.ts New TS wrapper around Tauri Twitch auth commands + shell open helper.
apps/desktop/src/components/SignIn.tsx New in-app sign-in overlay implementing the DCF UX and error mapping.
apps/desktop/src/App.tsx Boot-time auth status check to switch between SignIn and ChatFeed.
apps/desktop/src-tauri/tauri.conf.json Adjusts shell plugin open configuration for Twitch verification URLs.
apps/desktop/src-tauri/src/twitch_auth/mod.rs Exposes new commands module and re-exports command/state types.
apps/desktop/src-tauri/src/twitch_auth/manager.rs Adds peek_login() and logout() helpers for UI/supervisor.
apps/desktop/src-tauri/src/twitch_auth/commands.rs New Tauri command surface + error mapping + unit tests.
apps/desktop/src-tauri/src/sidecar_supervisor.rs Supervisor now receives shared AuthManager + Notify and waits on it in waiting_for_auth.
apps/desktop/src-tauri/src/lib.rs Registers auth commands; builds/manages shared AuthState; passes shared auth + notifier to supervisor.

Comment thread apps/desktop/src/components/SignIn.tsx
Comment thread apps/desktop/src-tauri/src/lib.rs Outdated
Comment thread apps/desktop/src-tauri/src/twitch_auth/commands.rs Outdated
Comment thread apps/desktop/src-tauri/src/twitch_auth/commands.rs Outdated
- Switch wakeup notifier from notify_waiters() to notify_one() so the
  permit is stored if the supervisor isn't currently parked, preventing
  dropped login/logout signals.
- Degrade gracefully when reqwest::Client::builder() fails in setup
  instead of panicking the app (per docs/stability.md).
- Rename SignIn cancel button to "Start over" and add a generation
  counter so stale completeLogin() resolutions from a previous attempt
  can't accidentally authenticate the user.
@github-actions github-actions bot added the size/l 500-1000 lines changed label Apr 17, 2026
Refactors the twitch_auth commands to delegate to inherent AuthState
methods so they're directly testable without a Tauri AppHandle, then
adds tests covering: status helper logged_in/logged_out paths,
complete_login no_pending_flow path, logout permit-storing notify,
cancel_login idempotency, and the remaining AuthError variants
(Keychain, Json, Config).
Tauri command bodies can't be unit-tested without spinning up a Tauri
runtime + WebView2 host (mock_runtime crashes with STATUS_ENTRYPOINT_NOT_FOUND
on Windows). Standard pattern: keep #[tauri::command] functions as thin
adapters and put all branchable logic in a separately-testable module.

- Move AuthState, AuthStatus, DeviceCodeView, AuthCommandError, and the
  From<AuthError> impl into twitch_auth/auth_state.rs along with all
  unit tests (now reach 91.79% coverage on that file).
- commands.rs is now ~50 lines of pure adapter delegation. Added to
  codecov ignore list alongside lib.rs and main.rs (same rationale:
  Tauri framework wiring without testable branches).
- mod.rs re-exports updated; no external API change.

123 lib tests still pass, clippy clean.
@ImpulseB23 ImpulseB23 merged commit f52ac60 into main Apr 17, 2026
13 checks passed
@ImpulseB23 ImpulseB23 deleted the feat/twitch-auth-ui branch April 17, 2026 22:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rust Rust/Tauri changes size/l 500-1000 lines changed typescript Frontend/TypeScript changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants